<?php
namespace Core\Mvc\Entity\Adapter;

use Core\Forms\Form;
use Core\Mvc\Entity\EntityInterface;
use Phalcon\Mvc\User\Plugin;
use Phalcon\Di;

/**
 * Class Config
 * @package Core\Mvc\Entity\Adapter
 */
class Config extends Plugin implements EntityInterface
{
    /**
     * @var null
     */
    protected $_field = null;
    /**
     * @var \Core\Forms\Form;
     */
    protected $_form = null;
    /**
     * @var null
     */
    protected $_save = null;
    /**
     * @var
     */
    protected $_id;
    /**
     * @var
     */
    protected $_module;
    /**f
     * @var
     */
    public $contentModel;
    /**
     * @var array
     */
    protected $_links = [];

    /**
     * @var
     */
    protected $_entity;

    /**
     * @return mixed
     */
    public function getEntity()
    {
        return $this->_entity;
    }

    /**
     * @return string
     */
    public function getTitle(): string
    {
        if (!$this->getId()) {
            return false;
        }
        $field = formFieldInit($this->getField());
        foreach ($field as $key => $element) {
            if (isset($element['isTitle']) && $element['isTitle'] === true) {
                return (isset($this->{$key}) && $this->{$key}) ? $this->{$key} : '';
            }
        }
        return '';
    }

    /**
     * @param array $links
     * @return $this
     */
    public function setLinks(array $links)
    {
        $this->_links = $links;
        return $this;
    }

    /**
     * @return array
     */
    public function getLinks()
    {
        $this->eventsManager->fire('entity:links', $this, $this->_links);
        return $this->_links;
    }

    /**
     * @return null | bool
     */
    public function getSaveState()
    {
        return $this->_save;
    }

    /**
     * @param string $contentModel
     * @return $this
     */
    public function setContentModel(string $contentModel)
    {
        $this->contentModel = $contentModel;
        return $this;
    }

    /**
     * @return mixed
     */
    public function getContentModel()
    {
        return $this->contentModel;
    }

    /**
     * @param string $module
     * @return $this
     */
    public function setModule(string $module)
    {
        $this->_module = $module;
        return $this;
    }

    /**
     * @return string
     */
    public function getModule():string
    {
        return $this->_module;
    }

    /**
     * @param null $field
     * @return $this
     */
    public function setField($field = null)
    {
        if (is_string($this->_field)) {
            $this->_field = $this->config->get($this->_field);
        }elseif (is_array($field)){
            $this->_field = $field;
        }
        return $this;
    }

    /**
     * @return null
     */
    public function getField()
    {
        return $this->_field;
    }

    /**
     * @return bool
     */
    public function addForm()
    {
        return false;
    }

    /**
     * @return \Core\Forms\Form
     */
    public function editForm()
    {
        if (is_null($this->_field) || !is_array($this->_field)) {
            $this->setField();
        }

        $this->eventsManager->fire('entity:editForm', $this);
        $this->_form = $this->form->create($this->_field);
        if ($this->_form->isValid()) {
            $this->save();
        }
        return $this->_form;
    }

    /**
     * @param $id
     */
    public function setId($id)
    {
        $this->_id = $id;
    }

    /**
     * @return string
     */
    public function getId():string
    {
        return $this->_id;
    }

    /**
     * @return Form
     */
    public function getForm()
    {
        return $this->_form;
    }

    /**
     * @param Form $form
     * @return $this
     */
    public function setForm(Form $form)
    {
        $this->_form = $form;
        return $this;
    }

    /**
     * @return bool
     */
    public function delete()
    {
        return false;
    }

    /**
     * @return Config
     */
    public function save()
    {
        $this->eventsManager->fire('entity:saveBefore', $this);
        $data = $this->_form->getData();
        $options = $this->_form->getUserOptions();
        $storage = $options['storage'];
        if ($this->config->set($storage, $data)) {
            $this->_save = true;
        } else {
            $this->_save = false;
        }
        $this->eventsManager->fire('entity:saveAfter', $this);
        return $this;
    }

    /**
     * @return array
     */
    public function toArray()
    {
        return (array)$this;
    }

    public static function find(array $param = null)
    {
        if(!isset($param['_entity']) || !is_string($param['_entity'])){
            throw new \Exception('没有设置实体机读名');
        }
        $entity = $param['_entity'];
        $di = Di::getDefault();
        $configData = $di->getShared('config')->cache('configEntityNode');
        foreach ($configData as $key => $config) {
            $configObject = $di->getShared('entityManager')->get($entity);
            if(!($configObject instanceof Config)){
                throw new \Exception('实体类型或许不存在');
            }
            $configObject->setId($key);
            foreach ($config as $cvk => $cvv) {
                $configObject->{$cvk} = $cvv;
            }
            yield $configObject;
        }
        return $configData;
    }

    /**
     * @param array|null $param
     * @return Config
     * @throws \Exception
     */
    public static function findFirst(array $param = null)
    {
        if(!isset($param['_entity']) || !is_string($param['_entity'])){
            throw new \Exception('没有设置实体机读名');
        }
        $entity = $param['_entity'];
        if (is_null($param)) {
            $configData = self::find();
            return $configData->current();
        } else {
            $di = Di::getDefault();
            $configData = $di->getShared('config')->cache('configEntityNode');
            if (!isset($configData[$param['id']])) {
                throw new \Exception('配置' . $param['id'] . '不存在');
            }
            $configObject = $di->getShared('entityManager')->get($entity);
            if(!($configObject instanceof Config)){
                throw new \Exception('实体类型或许不存在');
            }
            $configObject->setId($param['id']);
            foreach ($configData[$param['id']] as $key => $value) {
                $configObject->{$key} = $value;
            }
            return $configObject;
        }
    }

}